package main

import (
	"fmt"
	"net"
	"strings"
)

/*
	Server 结构体，随着需求可能下面会有变动
*/
type Server struct {
	addr  string
	port  string
	users []User
}

/*
	newServer 创建server实例
*/
func newServer(addr string, port string) *Server {
	return &Server{addr: addr, port: port}
}

func (server *Server) StartServer() {
	/*
		开启网络监听 tcp协议，指定地址和端口
	*/
	listen, err := net.Listen("tcp", fmt.Sprintf("%s:%s", server.addr, server.port))
	if err != nil {
		fmt.Printf("服务器建立失败！%s\n", err.Error())
		panic(err.Error())
	}
	fmt.Println("服务器启动成功 127.0.0.1 3000")
	for {
		/*
			使用for循环阻塞代码～，持续的监听外部对该网络服务对访问
		*/
		connection, err := listen.Accept()
		if err != nil {
			continue
		}
		/*
			有访问就开启一个go程去处理
		*/
		go server.handler(connection)
	}
}

/*
	服务端对客户端消息处理的函数
*/
func (server *Server) handler(connection net.Conn) {
	str := []byte("连接建立成功！\n")
	_, err := connection.Write(str)
	if err != nil {
		return
	} //Write 像客户端终端写入内容通知客户端建立成功！
	msgFromClient := make([]byte, 1024)
	newUser := newUser(connection.RemoteAddr().String(), connection.RemoteAddr().String(), connection, make(chan string))
	server.users = append(server.users, *newUser)
	fmt.Printf("当前在线用户人数%d人\n", len(server.users))
	for _, item := range server.users {
		fmt.Println(item.name)
	}
	isLive := make(chan bool)

	go func() {
		for {
			/*
				for 循环持续监听来自客户端的消息
			*/
			readCount, err := connection.Read(msgFromClient)
			if err != nil {
				if err.Error() == "EOF" {
					err := connection.Close()
					if err != nil {
						return
					}
					quitMessage := fmt.Sprintf("%s下线了", connection.RemoteAddr().String())
					var quitIndex int
					for index, item := range server.users {
						if item.addr == connection.RemoteAddr().String() {
							quitIndex = index
						} else {
							item.msgChannel <- quitMessage + "\n"
						}
					}
					server.users = append(server.users[:quitIndex], server.users[quitIndex+1:]...)
					fmt.Printf("当前在线用户人数%d人\n", len(server.users))
					for _, item := range server.users {
						fmt.Println(item.name)
					}
				}
				return
			}
			//[:readCount-1] 删除末尾的回车
			messageStr := string(msgFromClient[:readCount-1])

			/*
				约定 命令操作
				who 打印当前客户端name
				quit 下线功能并通知
				rename=newName 重新命名
				@name=xxx 私聊模式
			*/

			if readCount < 1 { //如果可读的行数>0 才输出
				return
			}
			fmt.Println("action")

			hasColon := strings.Index(messageStr, "=") //判断是否包含=号
			if strings.ToUpper(messageStr) == "WHO" {
				for _, item := range server.users {
					if item.addr == connection.RemoteAddr().String() {
						item.msgChannel <- item.name + "\n"
					}
				}
			} else if messageStr == "quit" {
				err := connection.Close()
				if err != nil {
					return
				}
				quitMessage := fmt.Sprintf("%s下线了", connection.RemoteAddr().String())
				var quitIndex int
				for index, item := range server.users {
					if item.addr == connection.RemoteAddr().String() {
						quitIndex = index
					} else {
						item.msgChannel <- quitMessage + "\n"
					}
				}
				server.users = append(server.users[:quitIndex], server.users[quitIndex+1:]...)
				fmt.Printf("当前在线用户人数%d人\n", len(server.users))
				for _, item := range server.users {
					fmt.Println(item.name)
				}
			} else if hasColon > 0 { //大于0 也不能让=开头
				if len(messageStr) > 1 && messageStr[:1] == "@" {
					toUser := messageStr[1:hasColon]
					message := messageStr[hasColon+1:] + "\n"
					for i := range server.users {
						if server.users[i].name == toUser {
							server.users[i].msgChannel <- message
						}
					}
				} else if len(messageStr) > 6 && messageStr[:6] == "rename" {
					newName := messageStr[7:]
					for i := range server.users {
						if server.users[i].addr == connection.RemoteAddr().String() {
							server.users[i].name = newName
						}
					}
				}
			} else {
				for _, item := range server.users {
					if item.addr != connection.RemoteAddr().String() {
						sendMessage := fmt.Sprintf("%s说%s", connection.RemoteAddr().String(), messageStr) + "\n"
						item.msgChannel <- sendMessage
					}
				}
			}
			isLive <- true
		}
	}()
	//for {
	//	select {
	//	case <-isLive:
	//		print("alive")
	//	case <-time.After(time.Second * 5):
	//		connection.Close()
	//	}
	//}
}
